#include <stdio.h>
#include <stdlib.h>

#define MAX 100000

// step 1#: 定义哈希表大小
#define HASH_TABLE_SIZE MAX

// step 2#: 定义哈希表项结构
typedef struct {
    int count;  // 记录出现次数
} HashEntry;

// step 3#: 计算哈希值，直接用元素的值作为哈希表下标
int hash(int key) {
    return key;
}

int main() {
    int m, n;
    // step 4#: 读取两个数组的长度
    scanf("%d %d", &m, &n);

    // step 5#: 动态分配内存存储数组 A 和 B
    int* arrayA = (int*)malloc(m * sizeof(int));  // 数组 A 的指针
    int* arrayB = (int*)malloc(n * sizeof(int));  // 数组 B 的指针

    // step 6#: 读取数组 A 和 B 的元素
    for (int i = 0; i < m; ++i) {
        scanf("%d", &arrayA[i]);
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &arrayB[i]);
    }

    // step 7#: 创建哈希表 countA 和 countB，初始化为0
    HashEntry countA[HASH_TABLE_SIZE] = {0};  // 哈希表 countA 用于记录数组 A 中元素的出现次数
    HashEntry countB[HASH_TABLE_SIZE] = {0};  // 哈希表 countB 用于记录数组 B 中元素的出现次数

    // step 8#: 统计数组 A 中每个元素的出现次数
    for (int i = 0; i < m; ++i) {
        int index = hash(arrayA[i]);  // 获取当前元素的哈希值作为下标
        countA[index].count++;  // 增加该元素的出现次数
    }

    // step 9#: 统计数组 B 中每个元素的出现次数
    for (int i = 0; i < n; ++i) {
        int index = hash(arrayB[i]);  // 获取当前元素的哈希值作为下标
        countB[index].count++;  // 增加该元素的出现次数
    }

    // step 10#: 计算数组 A 和数组 B 中元素的匹配数量
    int total = 0;
    
    // step 11#: 遍历数组 A，对应哈希表位置计算匹配数量
    for (int i = 0; i < m; ++i) {
        int key = arrayA[i];  // 获取当前数组 A 元素的值
        // step 12#: 如果数组 B 中也存在该元素，计算匹配数量
        total += countA[hash(key)].count * countB[hash(key)].count;
        // step 13#: 将数组 A 中的元素数量归零，避免重复计算
        countA[hash(key)].count = 0;
    }

    // step 14#: 输出最终结果
    printf("%d\n", total);

    // step 15#: 释放动态分配的内存
    free(arrayA);  // 释放数组 A 的内存
    free(arrayB);  // 释放数组 B 的内存

    return 0;
}
